#ifndef _MAIN_H_
#define _MAIN_H_

#include "BaseType.h"
#include "AhciSpec.h"
//#include "list.h"
//#include "TraceLog.h"
//#include "util.h"


/*****************************************************************************
 *
 *  Debug Functions
 *
 ****************************************************************************/
#define LOG_FILE_NAME   "ahci_log.txt"

#define DBG_ERROR              0
#define DBG_WARNING            1
#define DBG_NORMAL             2
#define DBG_TRACE              3
#define DBG_FUNCTION           3

#define COMP_INIT            0x00000001
#define COMP_SCRIPT          0x00000002
#define COMP_ADD             0x00000004
#define COMP_REMOVE          0x00000008
#define COMP_CRING           0x00000010
#define COMP_ERING           0x00000020
#define COMP_TRING           0x00000040
#define COMP_RING            ( COMP_CRING | COMP_ERING | COMP_TRING )
#define COMP_MEMMGT          0x00000100
#define COMP_HW              0x00000200
#define COMP_XHC             0x00000400
#define COMP_SLOT            0x00000800
#define COMP_EP              0x00001000
#define COMP_ALL             0xFFFFFFFF

#define COMP_CNT 14

typedef struct _pci_dev_info{
    UCHAR      BusNum;
    UCHAR      DevNum;
    UCHAR      FuncNum;
    WORD       DeviceID;
    WORD       VendorID;
}PCI_DEV_INFO, *PPCI_DEV_INFO;

#define CMD_TABLE_HW_ADDRESS    ( 0x20000000 )







#define DISK_A_HW_ADDRESS       ( 33 * 1048576 )
#define CMD_TABLE_SIZE          ( 1  * 1048576 )
#define DISK_A_SIZE             ( 24 * 1024    )

#define DISK_B_HW_ADDRESS       ( 128 * 1048576 )
#define DISK_C_HW_ADDRESS       ( 256 * 1048576 )
#define DISK_BC_SIZE            ( 256 * 1048576 )
#define DISK_B_SIZE             ( 128 * 1048576 )
#define DISK_C_SIZE             ( 128 * 1048576 )


#define PAGE_SIZE 4096
#define OFFSET_IN_PAGE( _addr_ ) ( _addr_ & (PAGE_SIZE-1) )
#define SECTOR_SZ  512
#define SECTOR_SZ_BIT 9
#define ROUND_TO_NEXT_SSD_PAGE_BOUNDARY( _lba_ ) ( ( _lba_ + 63 ) & ( ~63 ) )
#define ROUND_TO_NEXT_PAGE(_addr_) ( ( _addr_ + 4095 ) & ( ~(4095) ) )
#define ROUND_TO_PAGE(_addr_) ( _addr_ & ( ~(4095) ) )

#define PU_NUM                  8
#define SSD_PAGE_SIZE           32768
#define SECTOR_NUM_PER_SSD_PAGE 64
#define SSD_PAGE_MAX_WRITE_NUM  256

#define PC_MEM_BA     ( 0x02000000 )
#define PC_MEM_LENGTH ( 0x400000   ) // 4M
#define PC_MEM_NUM    4

typedef struct _ahci_ext{
    PCI_DEV_INFO    PciDevInfo;
    ULONG           HBARegBaseAddress;
    ULONG*          CmdRegAddr;
    ULONG*          XferLenRegAddr;
    ULONG*          PcMemArray[ PC_MEM_NUM ];
    ULONG*          Mem1;
    ULONG*          Mem2;
    ULONG*          Mem3;
    ULONG*          FBRegAddress;
    ULONG*          PxCIRegAddress;

    PCOMMAND_HEADER CmdHeaderArray;
    PCOMMAND_TABLE  CmdTableArray;
    PRFIS           ReceivedFIS;

}AHCI_EXT, *PAHCI_EXT;

void    main(int argc, char**argv);
STATUS  FindAHCIDevice( PPCI_DEV_INFO PciDevInfo );
STATUS  SwInit( PAHCI_EXT AhciExt );
STATUS  SwTermiate( PAHCI_EXT AhciExt );
#if 0
STATUS  Initialize(int argc, char**argv);
STATUS CheckViaAhciDevice( PPCI_DEV_INFO PciDevInfo );
void    InitAhciExt( PAHCI_EXT AhciExt );
STATUS  HwInit( PAHCI_EXT AhciExt );

void    Terminate();
STATUS  HwTerminate( PAHCI_EXT AhciExt );

void usage(char** argv);
UCHAR ParseOpt( int argc, char** argv );

STATUS  SyncRWEDisk( PAHCI_EXT AhciExt, UCHAR DiskIndex, HOST_REQ_TYPE Type, UCHAR Tag, ULONG Offset, ULONG Length, PULONG DataCrc );
STATUS  BuildSubDiskCmd(PHOST_CMD HostCmd, UCHAR DiskIndex, HOST_REQ_TYPE Type, ULONG Offset, ULONG Length );
void    LBA2FlashAddr( ULONG LBA, PFLASH_ADDR pFlashAddr );
#endif

#endif // _MAIN_H
